#include "stdafx.h"
#include "main_generator.h"

/*
 * state
 *   0 : non_detect_if
 *   1 : detect_if
 */

BasicBlock *get_condition_block(code_type type, char **src) {
	char *start_src;
	BasicBlock *bb;
	while(next(src) != '(');
	start_src = *src;
	while(next(src) != ')');
	*((*src)-1) = 0;
	bb = make_basic_block(type, start_src);
	return bb;
}

bool detected_if(CFG *cfg, result *r, char **src) {
	BasicBlock *if_block;
	char c, str[1024], buffer[1024];
	int strIndex = 0;
	int state = 0, flag = 0;

	r->ends = create_list();
	memset(str, 0, 1024);
	while((c = next(src)) != 0) {
		str[strIndex++] = c;
		trim(buffer, str);
		if(state == 0) {
			if(!strncmp(buffer, "if", strlen("if"))) {
				// condition
				if_block = get_condition_block(ct_if, src);
				r->start = if_block;
				add_list(r->ends, if_block);
				state = 1;

				memset(str, 0, 1024);
				strIndex = 0;
			} else if(!strncmp(buffer, "else", strlen("else"))) {
				memset(str, 0, 1024);
				strIndex = 0;
				state = 1;
				flag++;
			}
		} else if(state == 1) {
			if(c == '{') {
				CFG *next_cfg = make_cfg();
				result_state rs = parsing(next_cfg, src);
				if(rs != none)
					return false;
				//attach_basic_block(cfg, if_block, next_cfg->start);
				attach_basic_block_multi_child(cfg, if_block, next_cfg->start->connect_bb_list);
				merge_list(r->ends, next_cfg->end->parent_list);

				detach_body(next_cfg);
					
				memset(str, 0, 1024);
				strIndex = 0;
				state = 0;
				if(flag == 1) {
					remove_list(r->ends, if_block);
				}
				
			} else if(c == ';') {
				result second_res = { 0, 0 };
				bool existed_else = true;
				BasicBlock *body ;
				if(!strncmp(buffer, "if", strlen("if"))) {
					unnext(src, strlen(str));
						
					if(detected_if(cfg, &second_res, src) == false) {
						return false;
					}
					merge_list(r->ends, second_res.ends);
					existed_else = false;
				} else if(!strncmp(buffer, "for", strlen("for"))) {
					unnext(src, strlen(str));

					if(detected_for(cfg, &second_res, src) == false)  {
						return false;
					}
					merge_list(r->ends, second_res.ends);
				} else if(!strncmp(buffer, "while", strlen("while"))) {
					unnext(src, strlen(str));
					if(detected_while(cfg, &second_res, src) == false) {
						return false;
					}
					merge_list(r->ends, second_res.ends);
				} else if(!strncmp(buffer, "switch", strlen("switch"))) {
					unnext(src, strlen(str));

					if(detected_switch(cfg, &second_res, src) == false)
						return false;
					merge_list(r->ends, second_res.ends);
				} else {
					str[strIndex-1] = 0;
					body = make_basic_block(ct_statement, buffer);
					attach_basic_block(cfg, if_block, body);
					add_list(r->ends, body);	
				}

				if(second_res.ends) {
					attach_basic_block(cfg, if_block, second_res.start);
					destroy_list(second_res.ends);
				}

				if(flag == 1 && existed_else == true) {
					remove_list(r->ends, if_block);
				}

				memset(str, 0, 1024);
				strIndex = 0;
				state = 0;
			}
		}
	}

	unnext(src, strlen(str));

	return true;
}